package ginplus

import (
	"reflect"
)

// HandlerMappingChain 处理器调用链，以controller为维度
type HandlerMappingChain struct {
	controller      iController       // 处理器对象
	ctrlName        string            // controller名称
	ctrlFullName    string            // controller完整名称（包含包名）
	requestMapping  string            // controller的请求映射路径
	ctrlType        ControllerType    // 控制器类型
	fieldTag        reflect.StructTag // 标记在controller上的tag
	handlerMappings []*HandlerMapping // 处理器映射
}

// HandlerMapping 处理器映射，controller方法维度
type HandlerMapping struct {
	url          string              // 处理器映射url
	method       string              // 请求方式
	fun          HandlerMethod       // 处理器函数
	handlerChain HandlerMappingChain // 处理器调用链
	fieldTag     reflect.StructTag   // 标识该方法的tag
}

func (my *HandlerMapping) GetFullControllerName() string {
	return my.handlerChain.ctrlFullName
}

func (my *HandlerMapping) GetMethodName() string {
	return my.fun.funName
}

func (my *HandlerMapping) HasTag(tagName string) bool {
	// 1、方法未定义tag，则controller的tag生效
	// 2、方法定义了tag，则则方法自己定义的tag生效
	if _, ok := my.fieldTag.Lookup(tagName); ok {
		return true
	}
	_, ok := my.handlerChain.fieldTag.Lookup(tagName)
	return ok
}

func (my *HandlerMapping) GetTag(tagName string) string {
	// 1、方法未定义tag，则controller的tag生效
	// 2、方法定义了tag，则则方法自己定义的tag生效
	if val, ok := my.fieldTag.Lookup(tagName); ok {
		return val
	}
	return my.handlerChain.fieldTag.Get(tagName)
}

// HandlerMethod 处理器映射函数对象
type HandlerMethod struct {
	funName   string            // 方法名称
	rvFun     reflect.Value     // 方法的反射值
	funParams []HandlerFunParam // 方法入参对象
}

// HandlerFunParam 处理器映射函数入参对象
type HandlerFunParam struct {
	definedSpecialParamType DefinedSpecialParamTypeEnum // 定义的特殊参数类型
	definedParamIsPtr       bool                        // 定义的参数是否为指针类型：true -> 是；false -> 否
	rtParam                 reflect.Type                // 参数的 reflect.Type 值
	pName                   string                      // 参数名称
	defaultValMap           map[string]string           // 参数字段默认值（只支持结构体参数），使用default TAG声明
}
